#include <string.h>
#include <pthread.h>
#include "task_message.h"
#include "ipmi_netfn.h"

static message_queue_t message_queue[MESSAGE_QUEUE_SIZE];

pthread_mutex_t message_queue_mutex;

static int16 get_message_queue(payload_info_t* payload_info, channel_info_t* channel_info);

void task_message(void *params)
{
    int i = 0;
    cmd_assigments_t ptr_cmd;
    memset(&message_queue, 0, sizeof(message_queue));
    payload_info_t payload_info_req;
    payload_info_t payload_info_res;
    channel_info_t channel_info;
    uint8* request = NULL;
    uint16 request_size = 0;
    uint8* response = NULL;
    uint16 response_size = 0;
    show_command_info();

    pthread_mutex_init(&message_queue_mutex, NULL);
    while(1){
        if(get_message_queue(&payload_info_req, &channel_info)){
            memcpy(&payload_info_res, &payload_info_req, sizeof(payload_info_t));
            payload_info_res.data[payload_info_res.start_of_request] = 0xC1;
            payload_info_res.size_of_request = 1;
            get_command(payload_info_req.netfn, payload_info_req.cmd, (uint8*)&ptr_cmd);
            if(ptr_cmd.command_entrance){
                request = &payload_info_req.data[payload_info_req.start_of_request];
                request_size = payload_info_req.size_of_request;
                response = &payload_info_res.data[payload_info_res.start_of_request];
                payload_info_res.size_of_request = ptr_cmd.command_entrance(request, request_size, response);
            }
            channel_info.response.send((uint8*)&payload_info_res, (uint8*)&channel_info);
        }
    }
    pthread_mutex_destroy(&message_queue_mutex);
}

int16 set_message_queue(payload_info_t* payload_info, channel_info_t* channel_info)
{
    int i = 0;
    for(i=0; i<MESSAGE_QUEUE_SIZE; i++){
        pthread_mutex_lock(&message_queue_mutex);
        if(!message_queue[i].used){
            memcpy(&message_queue[i].payload_info, payload_info, sizeof(payload_info_t));
            memcpy(&message_queue[i].channel_info, channel_info, sizeof(channel_info_t));
            message_queue[i].used = TRUE;
            pthread_mutex_unlock(&message_queue_mutex);
            return 1;
        }
        pthread_mutex_unlock(&message_queue_mutex);
    }
    return 0;
}

static int16 get_message_queue(payload_info_t* payload_info, channel_info_t* channel_info)
{
    int i = 0;
    for(i=0; i<MESSAGE_QUEUE_SIZE; i++){
        pthread_mutex_lock(&message_queue_mutex);
        if(message_queue[i].used){
            memcpy(payload_info, &message_queue[i].payload_info, sizeof(payload_info_t));
            memcpy(channel_info, &message_queue[i].channel_info, sizeof(channel_info_t));
            message_queue[i].used = FALSE;
            pthread_mutex_unlock(&message_queue_mutex);
            return 1;
        }
        pthread_mutex_unlock(&message_queue_mutex);
    }
    return 0;
}

